package com.myprocessing.box;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import com.myprocessing.action.Action;
import com.myprocessing.gui.PGuiFrameApplet;
import com.myprocessing.gui.util.Coord;

public class Box implements Comparable<Box>, KeyListener {

	protected Box parent;
	
	public enum Listener{
		MOUSE,WII,KEY
	}
	
	protected Set<MouseListener> mouseListeners = new HashSet<MouseListener>();
	protected Set<WiiListener> wiiListeners = new HashSet<WiiListener>();
	protected Set<KeyListener> keyListeners = new HashSet<KeyListener>();

	protected SortedSet<Box> subBoxSet = new TreeSet<Box>();
	protected Map<String, Box> subBoxMap;

	protected String name;
	protected int zIndex;

	protected static PGuiFrameApplet pApplet;

	protected Coord position = new Coord();
	protected Coord size;

	protected boolean active = true;

	protected Action activateAction;
	protected Action deactivateAction;

	public Box() {
		super();
	}

	public Box(SortedSet<Box> subBoxes, int index) {
		super();
		this.subBoxSet = subBoxes;
		zIndex = index;
	}

	public void init() {
		if (position == null) {
			position = new Coord();
		}

		subBoxMap = new HashMap<String, Box>();
		for (Box box : subBoxSet) {
			box.parent = this;
			
			box.init();
			subBoxMap.put(box.getName(), box);

			if (box instanceof MouseListener) {
				mouseListeners.add((MouseListener) box);
			}
//			mouseListeners.addAll(box.mouseListeners);

			if (box instanceof KeyListener) {
				keyListeners.add((KeyListener) box);
			}
//			keyListeners.addAll(box.keyListeners);

			if (box instanceof WiiListener) {
				wiiListeners.add((WiiListener) box);
			}
//			wiiListeners.addAll(box.wiiListeners);
		}
	}

	public void addListener(Box box, Listener listener){
		switch (listener) {
		case MOUSE:
			mouseListeners.add((MouseListener)box);
			break;
		case WII:
			wiiListeners.add((WiiListener)box);
			break;
		case KEY:
			keyListeners.add((KeyListener)box);
			break;
		default:
			break;
		}
	}
	
	public void display() {
		if (isActive()) {
			pApplet.pushMatrix();
			pApplet.translate(position.getX(), position.getY());
			drawBox();
			for (Box box : subBoxSet) {
				try{
				box.display();
				} catch(Exception e){
					e.printStackTrace();
				}
			}
			pApplet.popMatrix();
		}
	}

	public void drawBox() {
	}

	public void onMousePress() {
		if (isActive()) {
			for (MouseListener mouseListener : mouseListeners) {
				mouseListener.onMousePress();
			}
			for (Box box : subBoxSet) {
				if (box.isActive()) {
					for (MouseListener mouseListener : box.mouseListeners) {
						mouseListener.onMousePress();
					}
				}
			}
		}
	}

	public void onMouseEnter() {
		if (isActive()) {
			for (MouseListener mouseListener : mouseListeners) {
				mouseListener.onMouseEnter();
			}
		}
	}

	public void onMouseOver() {
		if (isActive()) {
			for (MouseListener mouseListener : mouseListeners) {
				mouseListener.onMouseOver();
			}
		}
	}

	public void onMouseExit() {
		if (isActive()) {
			for (MouseListener mouseListener : mouseListeners) {
				mouseListener.onMouseExit();
			}
		}
	}

	public void onNotMouseOver() {
		if (isActive()) {
			for (MouseListener mouseListener : mouseListeners) {
				mouseListener.onNotMouseOver();
			}
		}
	}
	
	public void onKeyPressed(char key){
		System.out.println("KEY:" + key);
		
		if (isActive()) {
			for (KeyListener keyListener : keyListeners) {
				keyListener.onKeyPressed(key);
			}
		}
	}

	public Box getSubBox(String name) {
		return subBoxMap.get(name);
	}

	public void addSubBox(Box box) {
		box.setParent(this);
		subBoxSet.add(box);
//		parent.init();
	}

	public void removeSubBox(Box box) {
		subBoxSet.remove(box);
	}

	public int compareTo(Box compBox) {
		if (zIndex - compBox.zIndex == 0) {
			return -1;
		}
		return (zIndex - compBox.zIndex);
	}

	public SortedSet<Box> getSubBoxList() {
		return subBoxSet;
	}

	public void setSubBoxList(SortedSet<Box> subBoxList) {
		this.subBoxSet = subBoxList;
	}

	public int getZIndex() {
		return zIndex;
	}

	public void setZIndex(int index) {
		zIndex = index;
	}

	public Map<String, Box> getSubBoxMap() {
		return subBoxMap;
	}

	public void setSubBoxMap(Map<String, Box> subBoxMap) {
		this.subBoxMap = subBoxMap;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Coord getPosition() {
		return position;
	}

	public void setPosition(Coord position) {
		this.position = position;
	}

	public Coord getSize() {
		return size;
	}

	public void setSize(Coord size) {
		this.size = new Coord(size);
	}

	public static void setPApplet(PGuiFrameApplet applet) {
		pApplet = applet;
	}

	public boolean isActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
		
		if(active){
			Action.executeAction(activateAction);
		} else {
			Action.executeAction(deactivateAction);
		}
		
//		for(Box box: subBoxSet){
//			box.setActive(active);
//		}
	}
	
	public Box getParent() {
		return parent;
	}

	public void setParent(Box parent) {
		this.parent = parent;
	}

	public Coord getAbsolutePosition(){
		Coord result = new Coord(getPosition());
		
		if(parent != null){
			result.add(parent.getAbsolutePosition());
		}
		
		return result;
	}

	public Action getActivateAction() {
		return activateAction;
	}

	public void setActivateAction(Action activateAction) {
		this.activateAction = activateAction;
	}

	public Action getDeactivateAction() {
		return deactivateAction;
	}

	public void setDeactivateAction(Action deactivateAction) {
		this.deactivateAction = deactivateAction;
	}
}
